local extension = Package("aaa_steam_miao")
extension.extensionName = "aaa_steam"

local U = require "packages/utility/utility"
local RUtil = require "packages/aaa_fenghou/utility/rfenghou_util"
local DIY = require "packages/diy_utility/diy_utility"

Fk:loadTranslationTable{
  ["aaa_steam_miao"] = "动物朋友",
}

local rommel = General:new(extension, "steam__rommel", "west", 4)
Fk:loadTranslationTable{
  ["steam__rommel"] = "隆美尔",-- Erwin Rommel
  ["#steam__rommel"] = "帝国之鹰",
  ["cv:steam__rommel"] = "",
  ["designer:steam__rommel"] = "妙啊",
  ["illustrator:steam__rommel"] = "坦克世界",
}

local jijin = fk.CreateTriggerSkill{
  name = "steam__jijin",
  anim_type = "control",
  events = {fk.EventPhaseStart, fk.EventPhaseEnd},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and target == player and player.phase == Player.Discard then
      if event == fk.EventPhaseStart then
        return not player:isKongcheng()
        and table.find(player.room.alive_players, function(p) return p ~= player end) ~= nil
      else
        return true
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      local tos = player.room:askForChoosePlayers(player, targets, 1, 1, "#steam__jijin-choose", self.name, true)
      if #tos > 0 then
        self.cost_data = {tos = tos}
        return true
      end
    else
      local num = 0
      room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
        for _, move in ipairs(e.data) do
          if move.from == player.id and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand then
                num = num + 1
              end
            end
          end
        end
        return false
      end, Player.HistoryTurn)
      local targets = table.map(table.filter(room.alive_players, function (p)
        return p:getHandcardNum() <= num and not p:isNude()
      end), Util.IdMapper)
      if #targets == 0 then return false end
      local tos = room:askForChoosePlayers(player, targets, 1, 999, "#steam__jijin-dsicard:::"..num, self.name, true)
      if #tos > 0 then
        room:sortPlayersByAction(tos)
        self.cost_data = {tos = tos}
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local to = room:getPlayerById(self.cost_data.tos[1])
      local choices = {"0"}
      for i = 1, player:getHandcardNum() do
        table.insert(choices, tostring(i))
      end
      local num = tonumber(room:askForChoice(to, choices, self.name, "#steam__jijin-num:"..player.id))---@type integer
      if num > 0 then
        room:askForDiscard(player, num, num, false, "phase_discard", false)
      end
      return true
    else
      local tos = table.map(self.cost_data.tos, Util.Id2PlayerMapper)
      for _, to in ipairs(tos) do
        if not to:isNude() then
          room:askForDiscard(to, 2, 2, true, self.name, false)
        end
      end
    end
  end,
}
rommel:addSkill(jijin)

Fk:loadTranslationTable{
  ["steam__jijin"] = "疾进",
  [":steam__jijin"] = "弃牌阶段开始时，你可以令一名其他角色指定你的弃牌数；弃牌阶段结束时，你可以令手牌数不大于你本回合弃牌数的任意名角色各弃两张牌。",
  ["#steam__jijin-choose"] = "疾进：选择一名其他角色，令其指定你本阶段弃牌数！",
  ["#steam__jijin-num"] = "疾进：请决定 %src 此次弃牌阶段需要弃置多少手牌！",
  ["#steam__jijin-dsicard"] = "疾进：你可令手牌数不大于 %arg 的任意名角色各弃两张牌",
  
  ["$steam__jijin1"] = "",
  ["$steam__jijin2"] = "",
}

local qisheng = fk.CreateTriggerSkill{
  name = "steam__qisheng",
  anim_type = "offensive",
  events = {fk.TurnEnd},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and target == player then
      return #table.filter(player.room:getBanner("@$CenterArea") or {}, function (id)
        return Fk:getCardById(id).is_damage_card
      end) > 2
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    while player:isAlive() do
      local cards = table.filter(room:getBanner("@$CenterArea"), function (id)
        return Fk:getCardById(id).is_damage_card
      end)
      if #cards < 3 then break end
      cards = room:askForCardsChosen(player, player, 3, 3, { card_data = { { self.name, cards }  } },
      self.name, "#steam__qisheng-card")
      local get = room:askForCard(player, 1, 1, false, self.name, false, tostring(Exppattern{ id = cards }), "#steam__qisheng-prey", cards)[1]
      table.removeOne(cards, get)
      room:obtainCard(player, get, true, fk.ReasonPrey, player.id, self.name)
      cards = table.filter(cards, function (id) return room:getCardArea(id) == Card.DiscardPile end)
      if #cards == 0 then break end
      if player.dead then
        room:moveCardTo(cards[1], Card.DrawPile, nil, fk.ReasonPut, self.name, nil, false)
        break
      end
      local put = room:askForCard(player, 1, 1, false, self.name, false, tostring(Exppattern{ id = cards }), "#steam__qisheng-put", cards)[1]
      room:moveCardTo(put, Card.DrawPile, nil, fk.ReasonPut, self.name, nil, false)
      table.removeOne(cards, put)
      if player.dead or #cards == 0 or room:getCardArea(cards[1]) ~= Card.DiscardPile then break end
      local use = U.askForUseRealCard(room, player, cards, nil, self.name, "#steam__qisheng-use", {expand_pile = cards}, nil, false)
      if not (use and use.damageDealt) then break end
    end
  end,
}
qisheng.CenterArea = true
rommel:addSkill(qisheng)

Fk:loadTranslationTable{
  ["steam__qisheng"] = "奇胜",
  [":steam__qisheng"] = "回合结束时，你可以选择中央区的三张伤害牌，依次置入手牌、置于牌堆顶、使用，若以此法使用的牌造成了伤害，则重复此流程。",
  ["#steam__qisheng-card"] = "奇胜：选择三张伤害牌，依次置入手牌、置于牌堆顶、使用",
  ["#steam__qisheng-prey"] = "奇胜：选择一张置入手牌",
  ["#steam__qisheng-put"] = "奇胜：选择一张置于牌堆顶",
  ["#steam__qisheng-use"] = "奇胜：请使用此牌！",
  
  ["$steam__qisheng1"] = "",
  ["$steam__qisheng2"] = "",
}

local manstein = General:new(extension, "steam__manstein", "west", 3)
Fk:loadTranslationTable{
  ["steam__manstein"] = "曼施坦因",-- Erich von Manstein
  ["#steam__manstein"] = "失去的胜利",
  ["cv:steam__manstein"] = "易大剧",
  ["designer:steam__manstein"] = "妙啊",
  ["illustrator:steam__manstein"] = "坦克世界",
  ["~steam__manstein"] = "Der Feldmarschall von Preußen kapituliert nie.（普鲁士的陆军元帅决不投降！）",
}

local shanji = fk.CreateTriggerSkill{
  name = "steam__shanji",
  anim_type = "offensive",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Start
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local prompt = "#steam__shanji-choose"
    local mark = player:getMark("steam__shanji_last")
    if mark ~= 0 then
      prompt = "#steam__shanji-again:"..mark
    end
    local targets = table.map(room.alive_players, Util.IdMapper)
    if #targets == 0 then return false end
    local tos = room:askForChoosePlayers(player, targets, 1, 1, prompt, self.name, data ~= "steam__juantu", true)
    if #tos > 0 then
      self.cost_data = {tos = tos}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    local last = player:getMark("steam__shanji_last")
    room:setPlayerMark(player, "steam__shanji_last", to.id)
    local num = 1
    if to.id == last then num = 0 end
    room:damage { from = player, to = to, damage = num, skillName = self.name }
  end,
}
manstein:addSkill(shanji)

Fk:loadTranslationTable{
  ["steam__shanji"] = "闪击",
  [":steam__shanji"] = "准备阶段，你可以对一名角色造成1点伤害；若与你上次选择的角色相同，此伤害-1。",
  ["#steam__shanji-choose"] = "闪击：你可以对一名角色造成1点伤害",
  ["#steam__shanji-again"] = "闪击：你可以对一名角色造成1点伤害，若选择 %src，则伤害-1。",
  ["$steam__shanji1"] = "Offensive ist die beste Verteidigung.（进攻是最好的防守。）",
}

local tuique = fk.CreateTriggerSkill{
  name = "steam__tuique",
  anim_type = "support",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Finish
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local prompt = "#steam__tuique-choose"
    local mark = player:getMark("steam__tuique_last")
    if mark ~= 0 then
      prompt = "#steam__tuique-again:"..mark
    end
    local targets = table.map(room.alive_players, Util.IdMapper)
    if #targets == 0 then return false end
    local tos = room:askForChoosePlayers(player, targets, 1, 1, prompt, self.name, data ~= "steam__juantu", true)
    if #tos > 0 then
      self.cost_data = {tos = tos}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    local last = player:getMark("steam__tuique_last")
    room:setPlayerMark(player, "steam__tuique_last", to.id)
    local num = 1
    if last ~= 0 and to.id ~= last then num = 2 end
    room:recover { num = num, skillName = self.name, who = to, recoverBy = player }
  end,
}
manstein:addSkill(tuique)

Fk:loadTranslationTable{
  ["steam__tuique"] = "退却",
  [":steam__tuique"] = "结束阶段，你可以令一名角色回复1点体力；若与你上次选择的角色不同，回复量+1。",
  ["#steam__tuique-choose"] = "退却：你可以令一名角色回复1点体力",
  ["#steam__tuique-again"] = "退却：你可以令一名角色回复1点体力，若未选择 %src，回复量+1。",
  ["$steam__tuique1"] = "Ein Krieg ist erst dann verloren, wenn man ihn als verloren betrachtet.（唯有承认失败时，战争才会失败。）",
}

local juantu = fk.CreateTriggerSkill{
  name = "steam__juantu",
  anim_type = "drawcard",
  events = {fk.CardUsing},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and target.phase ~= Player.NotActive and target ~= player and player:usedSkillTimes(self.name) == 0 then
      return #player.room.logic:getEventsOfScope(GameEvent.UseCard, 4, function(e)
        local use = e.data[1]
        return use.from == target.id
      end, Player.HistoryTurn) > 3
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if data == "steam__juantu" or room:askForSkillInvoke(player, self.name, nil, "#steam__juantu-invoke:::"..4) then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:drawCards(4, self.name)
    if player.dead then return end
    local all_choices = {"steam__shanji", "steam__tuique", self.name}
    local choices = table.filter(all_choices, function (skill)
      return player:hasShownSkill(skill, true)
    end)
    if #choices == 0 then -- 小心各种奇怪的发动方法
      room:invalidateSkill(player, self.name, "-turn")
      return
    end
    local skill = room:askForChoice(player, choices, self.name, "#steam__juantu-choice", true, all_choices)
    room:handleAddLoseSkills(player, "-" .. skill)
    local triggerSkill = Fk.skills[skill]---@type TriggerSkill
    if triggerSkill and triggerSkill:isInstanceOf(TriggerSkill) then
      triggerSkill:doCost(triggerSkill.events[1], target, player, "steam__juantu")
    end
  end,
}
manstein:addSkill(juantu)

Fk:loadTranslationTable{
  ["steam__juantu"] = "卷土",
  [":steam__juantu"] = "每回合限一次，一名其他角色于其回合内使用牌时，若其本回合至少使用四张牌，你可以摸四张牌，若如此做，你须移去一个武将牌上的技能并发动一次。",
  ["#steam__juantu-invoke"] = "卷土：你可以摸 %arg 张牌，然后移去一个武将牌上的技能并发动之",
  ["#steam__juantu-choice"] = "请选择一个技能，移去并发动之",
  ["$steam__juantu1"] = "Wer versucht, alles auf einmal festzuhalten, hält am Ende gar nichts mehr fest.（如果你试图一次解决所有问题，那就什么也做不到。）",
}

local marshall = General:new(extension, "steam__marshall", "west", 3)
Fk:loadTranslationTable{
  ["steam__marshall"] = "马歇尔",-- George Catlett Marshall
  ["#steam__marshall"] = "纵横捭阖",
  ["cv:steam__marshall"] = "",
  ["designer:steam__marshall"] = "妙啊",
  ["illustrator:steam__marshall"] = "坦克世界",
}

local dengta = fk.CreateTriggerSkill{
  name = "steam__dengta",
  anim_type = "control",
  events = {fk.AfterCardsMove, fk.HpChanged},
  derived_piles = "steam_treaty",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.HpChanged then
        return not target.dead and target.hp == 1 and target:isWounded()
        and not table.contains(player:getTableMark("steam__dengta_recover"), target.id)
      else
        local room = player.room
        local tos = {}
        for _, move in ipairs(data) do
          local temp = room:getPlayerById(move.to)
          if temp and temp:isAlive() and temp:getHandcardNum() == 1 and
          not table.contains(player:getTableMark("steam__dengta_put"), temp.id)
          and move.toArea == Card.PlayerHand then
            table.insertIfNeed(tos, temp.id)
          end
          temp = room:getPlayerById(move.from)
          if temp and temp:isAlive() and temp:getHandcardNum() == 1 and
          not table.contains(player:getTableMark("steam__dengta_put"), temp.id)
          and table.find(move.moveInfo, function (info) return info.fromArea == Card.PlayerHand end) then
            table.insertIfNeed(tos, temp.id)
          end
        end
        if #tos > 0 then
          self.cost_data = tos
          return true
        end
      end
    end
  end,
  on_trigger = function (self, event, target, player, data)
    if event == fk.HpChanged then
      return self:doCost(event, target, player, data)
    end
    local tos = table.simpleClone(self.cost_data)
    local room = player.room
    room:sortPlayersByAction(tos)
    for _, pid in ipairs(tos) do
      if not player:hasSkill(self) then break end
      local to = room:getPlayerById(pid)
      if not to.dead and to:getHandcardNum() == 1 and not table.contains(player:getTableMark("steam__dengta_put"), to.id) then
        self:doCost(event, target, player, pid)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.HpChanged then
      if player.room:askForSkillInvoke(player, self.name, nil, "#steam__dengta-recover:"..target.id) then
        self.cost_data = {tos = {target.id}}
        return true
      end
    else
      if player.room:askForSkillInvoke(player, self.name, nil, "#steam__dengta-put:"..data) then
        self.cost_data = {tos = {data}}
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.AfterCardsMove then
      local to = room:getPlayerById(self.cost_data.tos[1])
      room:addTableMark(player, "steam__dengta_put", to.id)
      player:addToPile("steam_treaty", to:getCardIds("h"), true, self.name)
      if not to.dead then
        to:drawCards(3, self.name)
      end
    else
      room:addTableMark(player, "steam__dengta_recover", target.id)
      room:recover { num = 2, skillName = self.name, who = target, recoverBy = player }
    end
  end,
}
marshall:addSkill(dengta)

Fk:loadTranslationTable{
  ["steam__dengta"] = "灯塔",
  [":steam__dengta"] = "每名角色各限一次，一名角色手牌数变为1时，你可以令其将手牌置于你的武将牌旁，称为“约”，然后其摸三张牌；一名角色的体力值变为1时，你可以令其回复2点体力值。",
  ["steam_treaty"] = "约",
  ["#steam__dengta-recover"] = "灯塔：你可以令 %src 回复 2 点体力值（每名角色限一次）",
  ["#steam__dengta-put"] = "灯塔：你可以将 %src 手牌置入“约”，令其摸三张牌（每名角色限一次）",
}

local yange = fk.CreateTriggerSkill{
  name = "steam__yange",
  anim_type = "offensive",
  events = {fk.TurnStart},
  derived_piles = "steam_treaty",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and #player:getPile("steam_treaty") > 0 and player:usedSkillTimes(self.name, Player.HistoryRound) == 0 then
      return not target.dead and target:isWounded()
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local ids = table.filter(player:getPile("steam_treaty"), function (id)
      local c = Fk:getCardById(id)
      return player:canUseTo(c, target, {bypass_distances = true, bypass_times = true})
    end)
    local chosen = room:askForCard(player, 1, 1, false, self.name, true, tostring(Exppattern{ id = ids }),
    "#steam__yange-use:"..target.id, "steam_treaty")
    if #chosen > 0 then
      self.cost_data = {cards = chosen, tos = {target.id}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local card = Fk:getCardById(self.cost_data.cards[1])
    room:useCard{from = player.id, tos = {{target.id}}, card = card, extraUse = true}
    if player.dead then return end
    if table.contains(player:getTableMark("steam__dengta_put"), target.id)
     or table.contains(player:getTableMark("steam__dengta_recover"), target.id) then
      if room:askForSkillInvoke(player, self.name, nil, "#steam__yange-reset") then
        RUtil.resetSkill(player, self.name)
        if target.dead then return end
        local x = target.hp - 1
        if x > 0 then
          room:loseHp(target, x, self.name)
        elseif x < 0 then
          room:recover { num = -x, skillName = self.name, who = target, recoverBy = player }
        end
        if target.dead then return end
        local moves = {}
        local cards1, cards2 = {}, {}
        if not target:isKongcheng() then
          cards1 = target:getCardIds("h")
          table.insert(moves, {
            ids = cards1,
            from = target.id,
            toArea = Card.Processing,
            moveReason = fk.ReasonExchange,
            skillName = self.name,
            proposer = player.id,
          })
        end
        if #player:getPile("steam_treaty") > 0 then
          cards2 = player:getPile("steam_treaty")
          table.insert(moves, {
            ids = cards2,
            from = player.id,
            toArea = Card.Processing,
            moveReason = fk.ReasonExchange,
            skillName = self.name,
            proposer = player.id,
          })
        end
        if #moves == 0 then return end
        room:moveCards(table.unpack(moves))
        cards2 = table.filter(cards2, function (id) return room:getCardArea(id) == Card.Processing end)
        cards1 = table.filter(cards1, function (id) return room:getCardArea(id) == Card.Processing end)
        moves = {}
        if player:hasSkill(dengta) and #cards1 > 0 then
          table.insert(moves, {
            ids = cards1,
            to = player.id,
            toArea = Card.PlayerSpecial,
            moveReason = fk.ReasonExchange,
            skillName = self.name,
            proposer = player.id,
            specialName = "steam_treaty",
          })
        end
        if not target.dead and #cards2 > 0 then
          table.insert(moves, {
            ids = cards2,
            to = target.id,
            toArea = Card.PlayerHand,
            moveReason = fk.ReasonExchange,
            skillName = self.name,
            proposer = player.id,
          })
        end
        if #moves > 0 then
          room:moveCards(table.unpack(moves))
        end
        room:cleanProcessingArea(table.connect(cards1, cards2), self.name)
      end
    end
  end,
}
marshall:addSkill(yange)

Fk:loadTranslationTable{
  ["steam__yange"] = "颜革",
  [":steam__yange"] = "每轮限一次，已受伤角色回合开始时，你可以对其使用一张“约”；若你对其发动过“灯塔”，你可以重置“颜革”，令其将体力值调整为1并用所有手牌交换“约”。",
  ["#steam__yange-use"] = "颜革：你可以对 %src 使用一张“约”",
  ["#steam__yange-reset"] = "颜革：你可以重置“颜革”，令其将体力值调整为1，用所有手牌交换“约”",
}

local stalin = General:new(extension, "steam__stalin", "west", 4)
Fk:loadTranslationTable{
  ["steam__stalin"] = "斯大林",-- Joseph Vissarionovich Stalin
  ["#steam__stalin"] = "钢铁",
  ["cv:steam__stalin"] = "",
  ["designer:steam__stalin"] = "妙啊",
  ["illustrator:steam__stalin"] = "克里姆林宫",
}

-- 重名了
local yizhii = fk.CreateTriggerSkill{
  name = "steam__yizhii",
  anim_type = "control",
  frequency = Skill.Compulsory,
  events = {fk.GameStart, fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then return true end
      local useEvent = player.room.logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
        local use = e.data[1]
        return use.from == player.id
      end, Player.HistoryRound)[1]
      if useEvent then
        return useEvent.data[1] == data
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      if player.seat == 1 then return end
      local players = table.simpleClone(room.players)
      table.removeOne(players, player)
      table.insert(players, 1, player)
      room:arrangeSeats(players)
      -- 千万别有人已经进回合咯
      if room.logic:getCurrentEvent():findParent(GameEvent.Turn) ~= nil then return end
      room:setCurrent(player)
    else
      local color = data.card:getColorString()
      room:setPlayerMark(player, "@steam__yizhii_owner-round", color)
      local hasUsed = {}
      room.logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
        local use = e.data[1]
        table.insertIfNeed(hasUsed, use.from)
      end, Player.HistoryRound)
      for _, p in ipairs(room:getOtherPlayers(player)) do
        if not table.contains(hasUsed, p.id) then
          room:doIndicate(player.id, {p.id})
          room:setPlayerMark(p, "@steam__yizhii-turn", color)
        end
      end
    end
  end,

  refresh_events = {fk.TurnStart, fk.CardUsing},
  can_refresh = function (self, event, target, player, data)
    if event == fk.TurnStart then
      return player:getMark("@steam__yizhii_owner-round") ~= 0
    else
      return target == player and player:getMark("@steam__yizhii-turn") ~= 0
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    local color = player:getMark("@steam__yizhii_owner-round")
    if event == fk.TurnStart then
      room:delay(150)
      room:doIndicate(player.id, table.map(room:getOtherPlayers(player), Util.IdMapper))
      for _, p in ipairs(room:getOtherPlayers(player)) do
        room:setPlayerMark(p, "@steam__yizhii-turn", color)
      end
    else
      room:setPlayerMark(player, "@steam__yizhii-turn", 0)
    end
  end,

  on_lose = function (self, player)
    player.room:setPlayerMark(player, "@steam__yizhii_owner-round", 0)
  end,
}
local yizhii_prohibit = fk.CreateProhibitSkill{
  name = "#steam__yizhii_prohibit",
  prohibit_use = function(self, player, card)
    local mark = player:getMark("@steam__yizhii-turn")
    if mark ~= 0 and card then
      return card:getColorString() ~= mark
      and not (card.color == Card.NoColor and #card.skillNames == 0) -- 禁止使用无色牌很危险
    end
  end,
}
yizhii:addRelatedSkill(yizhii_prohibit)

stalin:addSkill(yizhii)

Fk:loadTranslationTable{
  ["steam__yizhii"] = "意志",
  [":steam__yizhii"] = "锁定技，游戏开始时，将你的座次调整为一号位。每轮你使用第一张牌后，其他角色每回合第一张牌只能使用与此牌颜色相同的牌。",
  ["@steam__yizhii_owner-round"] = "意志",
  ["@steam__yizhii-turn"] = "被意志",
}

local bizheng = fk.CreateTriggerSkill{
  name = "steam__bizheng",
  anim_type = "defensive",
  events = {fk.DamageInflicted, fk.BeforeCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.DamageInflicted then
        return target == player and player:getMark("steam__bizheng_damage-turn") == 0
      elseif player:getMark("steam__bizheng_discard-turn") == 0 then
        for _, move in ipairs(data) do
          if move.from == player.id and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Player.Hand or info.fromArea == Player.Equip then
                return true
              end
            end
          end
        end
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local prompt = event == fk.DamageInflicted and "#steam__bizheng-damage" or "#steam__bizheng-discard"
    return player.room:askForSkillInvoke(player, self.name, nil, prompt)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local doBizheng = function ()
      if player:isKongcheng() then return end
      player:showCards(player:getCardIds("h"))
      while player:isAlive() and not player:isKongcheng() do
        local types = {}
        local cards = player:getCardIds("h")
        for _, id in ipairs(cards) do
          table.insertIfNeed(types, Fk:getCardById(id).type)
        end
        if #types <= 1 then break end
        local others = room:getOtherPlayers(player, false)
        if #others == 0 then break end
        room:askForYiji(player, cards, others, self.name, 1, #cards, "#steam__bizheng-give")
      end
    end
    if event == fk.DamageInflicted then
      room:setPlayerMark(player, "steam__bizheng_damage-turn", 1)
      doBizheng()
      return true
    else
      room:setPlayerMark(player, "steam__bizheng_discard-turn", 1)
      room:cancelMove(data, nil, function (move, info)
        return move.from == player.id and move.moveReason == fk.ReasonDiscard
        and (info.fromArea == Player.Hand or info.fromArea == Player.Equip)
      end)
      -- 感觉在这个时机插结很危险，还是用ExitFunc吧
      room.logic:getCurrentEvent():addExitFunc(function()
        doBizheng()
      end)
    end
  end,
}
stalin:addSkill(bizheng)

Fk:loadTranslationTable{
  ["steam__bizheng"] = "必争",
  [":steam__bizheng"] = "每回合各限一次，你受到伤害或弃置牌时，可以防止之，然后你须展示手牌并分配直至你的手牌中只有一种类型的牌。",
  ["#steam__bizheng-damage"] = "必争：你可以防止受到伤害，展示手牌并分配直至只剩一种类型",
  ["#steam__bizheng-discard"] = "必争：你可以防止弃置牌，展示手牌并分配直至只剩一种类型",
  ["#steam__bizheng-give"] = "必争：请分配手牌直至只剩一种类型",
}

local gaohuan = General:new(extension, "steam__gaohuan", "qi", 4)
local gaohuanWin = fk.CreateActiveSkill{ name = "steam__gaohuan_win_audio" }
gaohuanWin.package = extension
Fk:addSkill(gaohuanWin)
Fk:loadTranslationTable{
  ["steam__gaohuan"] = "高欢",
  ["#steam__gaohuan"] = "不辞履虎",
  ["designer:steam__gaohuan"] = "妙啊",
  ["illustrator:steam__gaohuan"] = "AI",
  ["cv:steam__gaohuan"] = "Kazami",
  ["~steam__gaohuan"] = "六镇扰乱，百姓愁怨，无复聊生…",
  ["$steam__gaohuan_win_audio"] = "盖天意人心，好生恶杀，吉凶报应，盖有由焉。",
}

local daozu = fk.CreateTriggerSkill{
  name = "steam__daozu",
  events = {fk.TargetConfirming, fk.EventPhaseStart},
  frequency = Skill.Quest,
  anim_type = "offensive",
  mute = true,
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and target == player and player:getQuestSkillState(self.name) == nil then
      if event == fk.TargetConfirming then
        return data.card.is_damage_card and data.from and data.from ~= player.id
      else
        return player.phase == Player.Start and table.every(player.room.alive_players, function (p)
          return p:isWounded()
        end)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.EventPhaseStart then return true end
    if player.room:askForSkillInvoke(player, self.name, nil, "#steam__daozu-ask:::"..data.card:toLogString()) then
      return true
    else
      player.room:updateQuestSkillState(player, self.name, true)
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.TargetConfirming then
      room:notifySkillInvoked(player, self.name)
      player:broadcastSkillInvoke(self.name, math.random(2))
      room:loseHp(player, 1, self.name)
      AimGroup:cancelTarget(data, player.id)
      if not player.dead then
        U.askForUseVirtualCard(room, player, data.card.name, nil, self.name, nil, false)
      end
    else
      room:updateQuestSkillState(player, self.name, false)
      player:broadcastSkillInvoke(self.name, 3)
      room:notifySkillInvoked(player, self.name, "big")
      room:handleAddLoseSkills(player, "-steam__daozu|steam__daozu_copy|steam__fuyue")
    end
  end,
}
gaohuan:addSkill(daozu)

local daozu_copy = fk.CreateTriggerSkill{
  name = "steam__daozu_copy",
  events = {fk.TargetConfirming},
  anim_type = "offensive",
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and target == player and data.from and data.from ~= player.id then
      return data.card.is_damage_card
    end
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#steam__daozu-ask:::"..data.card:toLogString())
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(daozu.name, math.random(2))
    room:loseHp(player, 1, self.name)
    AimGroup:cancelTarget(data, player.id)
    if not player.dead then
      U.askForUseVirtualCard(room, player, data.card.name, nil, self.name, nil, false)
    end
  end,
}
Fk:addSkill(daozu_copy)

Fk:loadTranslationTable{
  ["steam__daozu"] = "刀俎",
  [":steam__daozu"] = "使命技，当你成为其他角色的伤害牌的目标时，你可以失去1点体力，取消并视为使用此牌。"..
  "<br>成功：准备阶段，若所有角色均受伤，你将“刀俎”删去使命并获得“斧钺”；"..
  "<br>失败：放弃发动“刀俎”。",
  ["#steam__daozu-ask"] = "刀俎：你可以失去1点体力，取消你为%arg的目标，并视为使用之",
  ["steam__daozu_copy"] = "刀俎",
  [":steam__daozu_copy"] = "当你成为其他角色的伤害牌的目标时，你可以失去1点体力，取消并视为使用此牌。",

  ["$steam__daozu1"] = "刀俎在前，今欲为耕牛而不可得。",
  ["$steam__daozu2"] = "昧纤钩而食饵，终难逃汤镬。",
  ["$steam__daozu3"] = "尔朱无道，弑君虐民，正英雄立功之会！",
}

---@param p ServerPlayer
local doFuyue = function (p, choice, num, skillName)
  local room = p.room
  if choice == "draw" then
    p:drawCards(num, skillName)
  elseif choice == "discard" then
    room:askForDiscard(p, num, num, false, skillName, false)
  elseif choice == "recover" then
    room:recover { num = num, skillName = skillName, who = p, recoverBy = room.current }
  else
    room:loseHp(p, num, skillName)
  end
end

local fuyue = fk.CreateTriggerSkill{
  name = "steam__fuyue",
  events = {fk.EventPhaseStart},
  frequency = Skill.Quest,
  anim_type = "control",
  mute = true,
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and target == player and player:getQuestSkillState(self.name) == nil then
      if player.phase == Player.Discard then
        return true
      elseif player.phase == Player.Finish then
        local minHp, maxHp, minHand, maxHand = 999, 0, 999, 0
        for _, p in ipairs(player.room.alive_players) do
          minHp = math.min(minHp, p.hp)
          maxHp = math.max(maxHp, p.hp)
          minHand = math.min(minHand, p:getHandcardNum())
          maxHand = math.max(maxHand, p:getHandcardNum())
        end
        return (player.hp == maxHp and player:getHandcardNum() == maxHand)
        or (player.hp == minHp and player:getHandcardNum() == minHand)
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if player.phase == Player.Discard then
      room:notifySkillInvoked(player, self.name, "control")
      player:broadcastSkillInvoke(self.name, math.random(2))
      local x = player:getHandcardNum() - player.hp
      if x == 0 then return end
      local choice = room:askForChoice(player, {"steam__fuyue_changehp", "steam__fuyue_changehand"}, self.name, "#steam__fuyue-change")
      if choice == "steam__fuyue_changehp" then
        if x > 0 then
          choice = "recover"
        else
          choice = "losehp"
        end
      else
        if x > 0 then
          choice = "discard"
        else
          choice = "draw"
        end
      end
      x = math.abs(x)
      doFuyue(player, choice, x)
      if not player.dead then
        local tos = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper),
        1, 1, "#steam__fuyue-"..choice..":::"..x, self.name, false)
        if #tos > 0 then
          local to = room:getPlayerById(tos[1])
          doFuyue(to, choice, x)
        end
      end
    else
      local success = table.every(room.alive_players, function (p)
        return p.hp <= player.hp and p:getHandcardNum() <= player:getHandcardNum()
      end)
      -- 同时满足时，优先算成功
      room:updateQuestSkillState(player, self.name, not success)
      if success then
        room:notifySkillInvoked(player, self.name, "big")
        player:broadcastSkillInvoke(self.name, 3)
        room:handleAddLoseSkills(player, "-steam__fuyue|steam__fuyue_copy|steam__lubao")
      end
    end
  end,
}
gaohuan:addRelatedSkill(fuyue)

local fuyue_copy = fk.CreateTriggerSkill{
  name = "steam__fuyue_copy",
  events = {fk.EventPhaseStart},
  anim_type = "control",
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Discard
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(fuyue.name, math.random(2))
    local x = player:getHandcardNum() - player.hp
    if x == 0 then return end
    local choice = room:askForChoice(player, {"steam__fuyue_changehp", "steam__fuyue_changehand"}, self.name, "#steam__fuyue-change")
    if choice == "steam__fuyue_changehp" then
      if x > 0 then
        choice = "recover"
      else
        choice = "losehp"
      end
    else
      if x > 0 then
        choice = "discard"
      else
        choice = "draw"
      end
    end
    x = math.abs(x)
    doFuyue(player, choice, x)
    if not player.dead then
      local tos = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper),
      1, 1, "#steam__fuyue-"..choice..":::"..x, self.name, false)
      if #tos > 0 then
        local to = room:getPlayerById(tos[1])
        doFuyue(to, choice, x)
      end
    end
  end,
}
Fk:addSkill(fuyue_copy)

Fk:loadTranslationTable{
  ["steam__fuyue"] = "斧钺",
  [":steam__fuyue"] = "使命技，弃牌阶段开始时，你须将体力或手牌数调整至与另一项相等，然后令一名角色执行你此次调整的手牌或体力变动。"..
  "<br>成功：结束阶段，你的体力和手牌数均为全场最多，你将“斧钺”删去使命并获得“卤薄”；"..
  "<br>失败：结束阶段，你的体力值和手牌数均全场最少。",
  ["steam__fuyue_changehp"] = "调整体力值",
  ["steam__fuyue_changehand"] = "调整手牌数",
  ["#steam__fuyue-change"] = "斧钺：请选择调整你的体力值或手牌数，至另一值",
  ["#steam__fuyue-draw"] = "斧钺：令一名角色摸 %arg 张牌",
  ["#steam__fuyue-discard"] = "斧钺：令一名角色弃 %arg 张手牌",
  ["#steam__fuyue-recover"] = "斧钺：令一名角色回复 %arg 点体力",
  ["#steam__fuyue-losehp"] = "斧钺：令一名角色失去 %arg 点体力",
  ["steam__fuyue_copy"] = "斧钺",
  [":steam__fuyue_copy"] = "弃牌阶段开始时，你须将体力或手牌数调整至与另一项相等，然后令一名角色执行你此次调整的手牌或体力变动。",
  
  ["$steam__fuyue1"] = "兵革羽旄，金鼓旗帜，饰孤之怒尔。",
  ["$steam__fuyue2"] = "倘能效诸兄弟，纵斧钺加身，欢诚甘乐之！",
  ["$steam__fuyue3"] = "羲和揽辔六龙回，卤薄千官泊虎台！",
}

local lubao = fk.CreateTriggerSkill{
  name = "steam__lubao",
  events = {fk.BeforeCardsMove, fk.BeforeDrawCard},
  anim_type = "control",
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) then return end
    if event == fk.BeforeDrawCard then
      return target == player and data.num > 0
    else
      for _, move in ipairs(data) do
        if move.from == player.id and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Player.Hand or info.fromArea == Player.Equip then
              return true
            end
          end
        end
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if event == fk.BeforeDrawCard then
      local targets = table.filter(room:getOtherPlayers(player, false), function (p) return not p:isAllNude() end)
      if #targets == 0 then return false end
      local tos = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper),
      1, 1, "#steam__lubao-prey:::"..data.num, self.name, true)
      if #tos > 0 then
        self.cost_data = {tos = tos}
        return true
      end
    else
      local tos = room:askForChoosePlayers(player, table.map(room:getOtherPlayers(player, false), Util.IdMapper),
      1, 1, "#steam__lubao-put", self.name, true)
      if #tos > 0 then
        self.cost_data = {tos = tos}
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    if event == fk.BeforeDrawCard then
      local x = math.min(data.num, #to:getCardIds("hej"))
      local cards = room:askForCardsChosen(player, to, x, x, "hej", self.name)
      room:obtainCard(player, cards, false, fk.ReasonPrey, player.id, self.name)
      return true
    else
      local equips, judges, hands, equipRecord, judgeRecord, moves = {}, {}, {}, {}, {}, {}
      local ids = {}
      for _, move in ipairs(data) do
        if move.from == player.id and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Player.Hand or info.fromArea == Player.Equip then
              table.insert(ids, info.cardId)
            end
          end
        end
      end
      room:cancelMove(data, ids)
      for _, id in ipairs(ids) do
        local c = Fk:getCardById(id)
        local toArea = "$Hand"
        local sub_type = c.sub_type
        local prompt = "#steam__lubao-area:::"..c:toLogString()
        if c.type == Card.TypeEquip then
          -- 计算一下对方装备区的此装备栏有多少空位
          local rest = #to:getAvailableEquipSlots(sub_type) - (equipRecord[sub_type] or 0)
          if rest > 0 then
            toArea = room:askForChoice(player, {"$Hand", "$Equip"}, self.name, prompt)
          end
        elseif sub_type == Card.SubtypeDelayedTrick then
          if not to:hasDelayedTrick(c.name) and not table.contains(to.sealedSlots, Player.JudgeSlot) and judgeRecord[c.name] == nil then
            toArea = room:askForChoice(player, {"$Hand", "$Judge"}, self.name, prompt)
          end
        end
        if toArea == "$Equip" then
          equipRecord[sub_type] = (equipRecord[sub_type] or 0) + 1
          table.insert(equips, id)
        elseif toArea == "$Judge" then
          judgeRecord[c.name] = true
          table.insert(judges, id)
        else
          table.insert(hands, id)
        end
      end
      if #hands > 0 then
        table.insert(moves, {
          from = player.id,
          ids = hands,
          to = to.id,
          toArea = Player.Hand,
          moveReason = fk.ReasonGive,
          skillName = self.name,
          moveVisible = false,
          proposer = player.id,
        })
      end
      if #equips > 0 then
        table.insert(moves, {
          from = player.id,
          ids = equips,
          to = to.id,
          toArea = Player.Equip,
          moveReason = fk.ReasonJustMove,
          skillName = self.name,
          moveVisible = true,
          proposer = player.id,
        })
      end
      if #judges > 0 then
        table.insert(moves, {
          from = player.id,
          ids = judges,
          to = to.id,
          toArea = Player.Judge,
          moveReason = fk.ReasonJustMove,
          skillName = self.name,
          moveVisible = true,
          proposer = player.id,
        })
      end
      if #moves > 0 then
        room:moveCards(table.unpack(moves))
      end
    end
  end,
}
gaohuan:addRelatedSkill(lubao)

Fk:loadTranslationTable{
  ["steam__lubao"] = "卤簿",
  [":steam__lubao"] = "当你摸牌/弃牌时，可以改为获得一名其他角色的区域等量牌/置入一名其他角色区域内。",
  ["#steam__lubao-prey"] = "卤簿：你可以将摸牌改为获得一名其他角色区域内 %arg 张牌",
  ["#steam__lubao-put"] = "卤簿：你可以将你的弃牌置入一名其他角色区域内",
  ["#steam__lubao-area"] = "卤簿：请选择%arg置入的区域",

  ["$steam__lubao1"] = "越山渡河，万里无阻，老贼，此天亡汝！",
  ["$steam__lubao2"] = "剪凶徒，匡天下，一麾以清京洛。",
}




local wuzixu = General:new(extension, "steam__wuzixu", "wu", 4)
Fk:loadTranslationTable{
  ["steam__wuzixu"] = "伍子胥",
  ["#steam__wuzixu"] = "日暮途远",
  ["designer:steam__wuzixu"] = "妙啊",
  ["illustrator:steam__wuzixu"] = "AI",
  --["cv:steam__wuzixu"] = "",
  ["~steam__wuzixu"] = "",
}

local nixing = fk.CreateTriggerSkill{
  name = "steam__nixing",
  anim_type = "negative",
  events = {fk.EventPhaseStart, fk.DrawNCards, fk.TurnStart},
  frequency = Skill.Compulsory,
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) and target == player then
      if event == fk.EventPhaseStart then
        return player.phase == Player.Discard
      else
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local x = (room:getBanner("RoundCount") or 0) + 1
    if event == fk.EventPhaseStart then
      room:askForDiscard(player, x, x, false, "phase_discard", false, nil, "#steam__nixing-discard:::"..x)
      return true
    elseif event == fk.DrawNCards then
      data.n = x
    else
      room:setPlayerMark(player, "@@steam__nixing", (1 - player:getMark("@@steam__nixing")))
    end
  end,

  on_lose = function (self, player)
    player.room:setPlayerMark(player, "@@steam__nixing", 0)
  end,
  
  refresh_events = {fk.EventPhaseChanging},
  can_refresh = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player and player:getMark("@@steam__nixing") ~= 0
    and (data.to == Player.Discard or data.to == Player.Draw)
  end,
  on_refresh = function (self, event, target, player, data)
    data.to = (data.to == Player.Discard) and Player.Draw or Player.Discard
  end,
}
wuzixu:addSkill(nixing)

Fk:loadTranslationTable{
  ["steam__nixing"] = "逆行",
  [":steam__nixing"] = "锁定技，你的摸牌阶段摸牌数和弃牌阶段弃牌数为X（X为当前轮数+1）。回合开始时，交换你摸牌阶段和弃牌阶段的执行顺序。",
  ["@@steam__nixing"] = "逆行:摸弃互换",
  ["#steam__nixing-discard"] = "逆行：你的弃牌阶段被改为弃置 %arg 张手牌",
}

local liehen = fk.CreateActiveSkill{
  name = "steam__liehen",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  prompt = "#steam__liehen",
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, _, _, _, player)
    local to = Fk:currentRoom():getPlayerById(to_select)
    return #selected == 0 and to and player and to:getHandcardNum() ~= player:getHandcardNum()
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local to = room:getPlayerById(effect.tos[1])
    local cards = {}
    local x = to:getHandcardNum() - player:getHandcardNum()
    if x > 0 then
      cards = room:askForDiscard(to, x, x, false, self.name, false)
    else
      to:drawCards(-x, self.name)
    end
    while player:isAlive() do
      cards = table.filter(cards, function (id) return room:getCardArea(id) == Card.DiscardPile end)
      if #cards == 0 then break end
      local use = room:askForUseRealCard(player, cards, self.name, "#steam__liehen-use", {expand_pile = cards}, false, true)
      if not use then break end
      table.removeOne(cards, use.card:getEffectiveId())
      room:useCard(use)
    end
  end,
}
wuzixu:addSkill(liehen)

Fk:loadTranslationTable{
  ["steam__liehen"] = "烈恨",
  [":steam__liehen"] = "出牌阶段限一次，你可以选择一名角色，令其调整手牌数至与你相等，然后你依次使用其以此法弃置的可以使用的牌。",
  ["#steam__liehen"] = "烈恨：令一名角色调整手牌数至与你相等，然后使用其弃置的牌",
  ["#steam__liehen-use"] = "烈恨：请使用其弃置的牌",
}







return extension
